package com.franklin.java.service.database;

import com.franklin.java.entity.sql.JdbcInfo;
import com.franklin.java.icon.MybatisIcons;
import com.franklin.java.icon.PluginIcons;
import com.franklin.java.service.database.ui.AddDataSourceForm;
import com.franklin.java.service.database.ui.JdbcResultForm;
import com.franklin.plugins.common.collection.PrettyArrayList;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.*;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;

import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 自定义的JdbcConsole
 *
 * @author Franklin
 * @since 2021/9/24 14:14
 */
public class FranklinJdbcConsole extends AbstractJdbcConsole {

    private JdbcInfo jdbcInfo;

    private JdbcResultForm jdbcResultForm;

    public FranklinJdbcConsole(Project project, String sql) {
        super(project, sql);
        this.jdbcInfo = JdbcState.getLastJdbcInfo();
        this.jdbcResultForm = JdbcResultForm.getInstance(project);
    }


    @Override
    public boolean executeQuery() {
        try {
            if (Objects.isNull(jdbcInfo)) {
                return false;
            }
            JdbcService jdbcService = JdbcService.getInstance();
            jdbcService.addDataSource(jdbcInfo);
            jdbcService.executeQuery(
                jdbcInfo,
                sql + jdbcResultForm.getLimit(),
                jdbcResultForm.showResultInWindow(sql)
            );
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public JBPopup getDatasourceChoosingPopup() {
        List<String> items = new PrettyArrayList<>();
        List<Icon> icons = new PrettyArrayList<>();
        items.add("Add DataSource");
        icons.add(AllIcons.General.Add);

        Map<String, JdbcInfo> jdbcInfoMap = JdbcState.getJdbcInfoMap();
        jdbcInfoMap.forEach((dsName, jdbcInfo) -> {
            items.add(dsName);
            icons.add(MybatisIcons.logo);
        });

        JBPopupFactory jbPopupFactory = JBPopupFactory.getInstance();
        ListPopup popupMenu = jbPopupFactory.createListPopup(
            new BaseListPopupStep<>(
                "Choose DataSource",
                items,
                icons
            ) {
                @Override
                public @Nullable
                PopupStep<?> onChosen(String selectedValue, boolean finalChoice) {
                    if (selectedValue.equals("Add DataSource")) {
                        AddDataSourceForm addDataSourceForm = new AddDataSourceForm(project, FranklinJdbcConsole.this);
                        JPanel mainPanel = addDataSourceForm.getMainPanel();
                        JBPopup popup = jbPopupFactory.createComponentPopupBuilder(mainPanel, mainPanel)
                            .setTitle("Create A New DataSource")
                            .setCancelKeyEnabled(true)
                            .setCancelButton(new IconButton("close", AllIcons.Actions.CloseHovered))
                            .setTitleIcon(new ActiveIcon(MybatisIcons.logo))
                            .setMovable(true)
                            .setShowShadow(true)
                            .setResizable(true)
                            .setRequestFocus(true)
                            .setCancelOnClickOutside(false)
                            .createPopup();

                        addDataSourceForm.getCancelButton().addActionListener(actionEvent -> popup.cancel());

                        popup.showCenteredInCurrentWindow(project);
                    } else {
                        jdbcInfoMap.forEach((dsName, jdbcInfo) -> {
                            if (dsName.equals(selectedValue)) {
                                setJdbcInfo(jdbcInfo);
                                executeQuery();
                            }
                        });
                    }

                    return null;
                }
            }
        );
        return popupMenu;
    }

    public void setJdbcInfo(JdbcInfo jdbcInfo) {
        this.jdbcInfo = jdbcInfo;
    }

}
